package com.yuxue.util;

/**
 * 损失函数
 * 用于定义单个训练样本与真实值之间的误差
 */
public class LossFunction {

    /**
     * 计算均方误差损失：适用于回归问题
     * 函数的最小值为 0（当预测等于真实值时），最大值为无穷大
     * @param predictions 预测值
     * @param actuals 实际值
     * @return
     */
    public static double meanSquaredError(double[] predictions, double[] actuals) {
        double loss = 0.0;
        for (int i = 0; i < predictions.length; i++) {
            loss += (predictions[i] - actuals[i]) * (predictions[i] - actuals[i]);
        }
        return loss;
    }


    /**
     * 计算加权均方误差损失：适用于回归问题
     * @param predictions 预测值
     * @param actuals 实际值
     * @param weights 权重
     * @return
     */
    public static double weightedMeanSquaredError(double[] predictions, double[] actuals, double[] weights) {
        double loss = 0.0;
        for (int i = 0; i < predictions.length; i++) {
            loss += weights[i] * (predictions[i] - actuals[i]) * (predictions[i] - actuals[i]);
        }
        return loss;
    }


    /**
     * 计算交叉熵损失：适用于二分类问题
     * @param predictions 预测值
     * @param actualClass 实际类别
     * @return
     */
    public static double crossEntropyLoss(double[] predictions, int actualClass) {
        double loss = 0.0;
        for (int i = 0; i < predictions.length; i++) {
            if (i == actualClass) {
                loss -= Math.log(predictions[i]);
            } else {
                loss -= Math.log(1.0 - predictions[i]);
            }
        }
        return loss;
    }



    public static void main(String[] args) {

        double[] predictions = {0.2, 0.5, 0.3};
        double[] actuals = {0.1, 0.6, 0.4};
        double[] weights = {0.5, 0.3, 0.2};

        System.out.println("均方误差损失: " + meanSquaredError(predictions, actuals));
        System.out.println("加权均方误差损失: " + weightedMeanSquaredError(predictions, actuals, weights));

        // 测试交叉熵损失
        int actualClass = 1; // 实际类别为1
        System.out.println("交叉熵损失: " + crossEntropyLoss(predictions, actualClass));


    }
}
